home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i098: A trig/multi-base calculator
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Wayne Mesard <mesard@bbn.com>
- Posting-number: Volume 14, Issue 98
- Archive-name: calc
-
- [ This program evalues mathematical expressions, like
- calc '2 * 3 / sin 45'
- it works off the command line, or standard input.
- Yeah, you could consider this redundant given dc and bc, but
- I find this easier to use than either one of them.
- Porters beware of the machine.h / mch_defines stuff. --r$ ]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(195 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- BIN = ../bin/
- CFLAGS = -O
- X
- calc: $(BIN)calc
- X
- X$(BIN)calc: calc.c machine.h
- X $(CC) calc.c -lm -o $(BIN)calc
- X
- machine.h:
- X $(CC) mch_defines.c -o mch_defines
- X mch_defines > machine.h
- X rm mch_defines
- END_OF_FILE
- if test 195 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'POSTME' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'POSTME'\"
- else
- echo shar: Extracting \"'POSTME'\" \(0 characters\)
- sed "s/^X//" >'POSTME' <<'END_OF_FILE'
- END_OF_FILE
- if test 0 -ne `wc -c <'POSTME'`; then
- echo shar: \"'POSTME'\" unpacked with wrong size!
- fi
- # end of 'POSTME'
- fi
- if test -f 'calc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'calc.c'\"
- else
- echo shar: Extracting \"'calc.c'\" \(11315 characters\)
- sed "s/^X//" >'calc.c' <<'END_OF_FILE'
- X/**************************************************************************
- X * calc: a command-line calculator program *
- X * Copyright (c) 1988 Wayne Mesard *
- X * *
- X * This is free software. It may be reproduced, retransmitted, *
- X * redistributed and otherwise propogated at will, provided that *
- X * this notice remains intact and in place. *
- X * *
- X * Please direct bug reports, code enhancements and comments *
- X * to mesard@BBN.COM. *
- X * *
- X **************************************************************************/
- X
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <strings.h>
- X#include <math.h>
- X#include <setjmp.h>
- X
- X#define PIdiv180 0.017453292519943295
- X#define PI 3.14159265358979323846
- X#include "machine.h"
- X#ifdef Mch_Lsz
- X# define TwoToTheNLessOne (unsigned long)(1<<(Mch_Lsz-1))
- X#else /* Assume 16 bits */
- X# define TwoToTheNLessOne 32768
- X#endif
- X
- X#define MAXLINE 512
- X
- X#define OP "{(["
- X#define CP "})]"
- X#define SYMBOLS "{([+-/xX*%:&^|<>~gnpst" /* Used to distinguish unary from
- X binary minus. Letters at end of
- X string are ends of function names. */
- X
- X#define SYMBOL_LOWERS "xabcdef" /* Used to detect implied multiplication.
- X * Identifies these as symbols and not
- X * part of a function name.
- X */
- X
- X#define DECFMT "\t% .16g\n"
- X#define BINFMT "\tb%*s\n"
- X#define FLTFMT "\t% .*f\n"
- X#define HEXFMT "\th%lX\n"
- X#define OCTFMT "\to%lo\n"
- X#define ASCFMT "\t@%c\n"
- X
- jmp_buf err_recover;
- int abort_on_err = 0;
- double answer = 0.0;
- X
- main(argc, argv) /* calc: a desk-top calculator */
- int argc;
- char *argv[];
- X{
- X char s[MAXLINE];
- X int precision = -1;
- X char mode = '\0';
- X int getwhitlessline(), isatty();
- X int keepchecking = 1;
- X
- X for (argv++, argc--; argc && **argv == '-' && keepchecking; argv++, argc--)
- X switch ((*argv)[1]) {
- X case 'p':
- X if (isdigit((*argv)[2]))
- X precision = atoi( &(*argv)[2]);
- X else {
- X abort_on_err = 1;
- X error("bad argument to -p option");
- X }
- X break;
- X case 'e':
- X abort_on_err = 1;
- X break;
- X case 'd':
- X case 'h':
- X case 'o':
- X case 'b':
- X case '@':
- X mode = (*argv)[1];
- X break;
- X case '\0':
- X keepchecking = 0;
- X break;
- X default: /* Oops, this must be a unary minus, not an option. */
- X keepchecking = 0;
- X argv--;
- X argc++;
- X break;
- X }
- X
- X if (argc) {
- X s[0] = '\0';
- X while (argc-- > 0)
- X strcat (s, *argv++);
- X abort_on_err = 1;
- X Compute (mode, s, precision);
- X }
- X else {
- X if (isatty(0))
- X printf ("Enter equations. Blank line to terminate.\n");
- X setjmp(err_recover);
- X while (getwhitlessline (s))
- X Compute (mode, s, precision);
- X }
- X}
- X
- X
- Compute(mode, s, precision)
- char mode, *s;
- int precision;
- X{
- X double calc();
- X char *ftob(), binnum[MAXLINE];
- X
- X answer = calc(s);
- X switch(mode) {
- X case '\0':
- X case 'd':
- X if (precision >= 0)
- X printf(FLTFMT, precision, answer);
- X else
- X printf(DECFMT, answer);
- X break;
- X case 'h':
- X printf(HEXFMT, (unsigned long) answer);
- X break;
- X case 'o':
- X printf(OCTFMT, (unsigned long) answer);
- X break;
- X case 'b':
- X printf(BINFMT, (precision > 0 ? precision : 0),
- X ftob(binnum, answer));
- X break;
- X case '@':
- X printf(ASCFMT, (char) answer);
- X break;
- X }
- X}
- X
- X
- X
- X/*******
- X * When debugging uncomment this proc and change the following proc's name
- X * to calc2
- X *
- double calc(e)
- char *e;
- X{
- X double calc2();
- X double val;
- X
- X printf("calling with **%s**\n", e);
- X val = calc2(e);
- X printf("returning **%f**\n", val);
- X return(val);
- X}
- X*******/
- X
- X
- X/* Recursively, parse an equation string.
- X * This is hideously inefficient, since findop() is called on each invokation.
- X * O(n) would be possible if findop() where modified to walk through the string
- X * once and build a priority queue for evaluation of operators.
- X * But hey, the kids love it, and I know for a fact that my Data Structures
- X * prof never wrote a linear algorithm in his life:-)
- X */
- X
- double calc(eqn)
- char *eqn;
- X{
- X double vleft, temp;
- X long tempi;
- X char left[MAXLINE], eqncp[MAXLINE];
- X char *findop (), *opptr;
- X double btof();
- X
- X while (*eqn == ' ' || *eqn == '\t')
- X eqn++;
- X
- X if (!*eqn)
- X error("missing expression");
- X
- X else if (opptr = findop(eqn)) {
- X strncpy (left, eqn, opptr - eqn);
- X left[opptr - eqn] = '\0';
- X vleft = calc(left);
- X switch (*opptr) {
- X case '+':
- X return(vleft + calc(++opptr));
- X case '-':
- X return(vleft - calc(++opptr));
- X case '/':
- X if ((temp = calc(++opptr)) == 0.0)
- X error ("division by zero");
- X else
- X return(vleft / temp);
- X case 'x':
- X case 'X':
- X case '*':
- X return(vleft * calc(++opptr));
- X case '%':
- X if ((temp = fabs(floor (calc(++opptr)+0.5))) == 0.0 ||
- X temp > (TwoToTheNLessOne-1))
- X error("bad argument to modulo");
- X return((double)((long) (floor (vleft) + 0.5) %
- X (long) temp));
- X case ':':
- X return(pow(vleft, calc(++opptr)));
- X case '&':
- X return((double)((unsigned long)vleft &
- X (unsigned long)calc(++opptr)));
- X case '^':
- X return((double)((unsigned long)vleft ^
- X (unsigned long)calc(++opptr)));
- X case '|':
- X return((double)((unsigned long)vleft |
- X (unsigned long)calc(++opptr)));
- X case '<':
- X return((double)((unsigned long)vleft <<
- X (unsigned long)calc(++opptr)));
- X case '>':
- X return((double)((unsigned long)vleft >>
- X (unsigned long)calc(++opptr)));
- X
- X default: /* implied multiplication */
- X return(vleft * calc(opptr));
- X }
- X }
- X
- X else if (index (OP, *eqn)) {
- X strcpy(eqncp, ++eqn);
- X eqncp[strlen (eqncp) - 1] = '\0';
- X return(calc (eqncp));
- X }
- X
- X else if (*eqn == '+')
- X return(calc(eqn+1));
- X else if (*eqn == '-')
- X return(-1.0 * calc(eqn+1));
- X else if (*eqn == '~')
- X return((double)(~ (unsigned long)calc(eqn+1)));
- X
- X else if (strncmp(eqn, "sin", 3) == 0)
- X return(sin (calc(eqn+3) * PIdiv180));
- X else if (strncmp(eqn, "cos", 3) == 0)
- X return(cos (calc(eqn+3) * PIdiv180));
- X else if (strncmp(eqn, "tan", 3) == 0)
- X return(tan (calc(eqn+3) * PIdiv180));
- X else if (strncmp(eqn, "atan", 4) == 0)
- X return(atan (calc(eqn+4)) / PIdiv180);
- X
- X else if (strncmp(eqn, "sqrt", 4) == 0)
- X return(sqrt (calc(eqn+4)));
- X else if (strncmp(eqn, "log", 3) == 0)
- X return(log10 (calc(eqn+3)));
- X else if (strncmp(eqn, "ln", 2) == 0)
- X return(log (calc(eqn+2)));
- X else if (strncmp(eqn, "exp", 3) == 0)
- X return(exp (calc(eqn+3)));
- X else if (strncmp(eqn, "pi", 2) == 0 || strncmp(eqn, "PI", 2) == 0)
- X return(PI);
- X else if (strncmp(eqn, "prev", 4) == 0)
- X return(answer);
- X
- X else if (*eqn == 'h') {
- X sscanf(eqn+1, "%lx", &tempi);
- X return((double) tempi);
- X }
- X else if (*eqn == 'o') {
- X sscanf(eqn+1, "%lo", &tempi);
- X return((double) tempi);
- X }
- X else if (*eqn == 'b')
- X return(btof(eqn+1));
- X else if (*eqn == '@')
- X return((double) *(eqn+1));
- X else if (!(isdigit(*eqn) || *eqn == '.') )
- X error("illegal expression");
- X else
- X return(atof (eqn));
- X}
- X
- X
- X
- X/*
- X * Takes a parenthesized expression and returns a pointer to the closing paren.
- X */
- X
- char *findclose(s)
- char *s;
- X{
- X register int lev = 0;
- X
- X for (; *s && !(lev==1 && index(CP, *s)); s++)
- X if (index(OP, *s))
- X lev++;
- X else if (index(CP, *s))
- X lev--;
- X
- X if (!*s)
- X error("unmatched open paren");
- X else
- X return(s);
- X}
- X
- X
- X/** Precedence levels for binary operators **/
- X
- X#define OPTYPE int
- X#define NONOP 0
- X#define NULLOP 1
- X#define EXP 3
- X#define MULT 5
- X#define DIV 5
- X#define MOD 6
- X#define ADD 7
- X#define SUBTR 7
- X#define LSHIFT 8
- X#define RSHIFT 8
- X#define BAND 9
- X#define BXOR 10
- X#define BOR 11
- X
- char *findop(s)
- char *s;
- X{
- X register OPTYPE op;
- X OPTYPE bestop = NULLOP;
- X char *bestptr = 0;
- X register char last = '\0';
- X
- X while (*s) {
- X op = NONOP;
- X if (*s == ' ' || *s == '\t') { /* Don't let lasts get assigned to space */
- X s++;
- X continue;
- X }
- X else {
- X switch (*s) {
- X case ':':
- X op = EXP;
- X break;
- X case '%':
- X op = MOD;
- X break;
- X case 'x':
- X case 'X':
- X case '*':
- X if (!(*s=='x' && last=='e' && *(s+1)=='p')) /* exp() function */
- X op = MULT;
- X break;
- X case '/':
- X op = DIV;
- X break;
- X case '+':
- X /* "+" means unary plus (not add) if it follows a
- X * symbol or a function name.
- X */
- X if (!index(SYMBOLS, last))
- X op = ADD;
- X break;
- X case '-':
- X /* "-" means unary minus (not subtract) if it follows a
- X * symbol or a function name.
- X */
- X if (!index(SYMBOLS, last))
- X op = SUBTR;
- X break;
- X case '<':
- X op = LSHIFT;
- X break;
- X case '>':
- X op = RSHIFT;
- X break;
- X case '&':
- X op = BAND;
- X break;
- X case '^':
- X op = BXOR;
- X break;
- X case '|':
- X op = BOR;
- X break;
- X default:
- X /* Implied multiplication occurs when a digit or a
- X * close paren is followed by a func-call, or an open
- X * paren. The check for "co" and "at" is to distinguish
- X * 'c' and 'a' as hex digits and their appearance in
- X * "cos" and "atan".
- X */
- X if ((last && (isdigit(last) || index(CP, last))) &&
- X ((islower(*s) || index(OP, *s)) ||
- X (!isdigit(last) && isdigit(*s))) &&
- X (!index(SYMBOL_LOWERS, *s) ||
- X !strncmp("co", s, 2) || !strncmp("at", s, 2)))
- X op = MULT;
- X }
- X
- X if (op >= bestop) {
- X bestop = op;
- X bestptr = s;
- X }
- X }
- X
- X if (index(OP, *s))
- X s = findclose(s);
- X
- X last = *s++;
- X }
- X return(bestptr);
- X}
- X
- X
- X
- X/*
- X * Places a binary representation of "val" in the string "s" and returns
- X * a pointer to the start of that string. "val" should be (or will be coerced
- X * to )an integer between +/- 2^n, where n is the number of bits in a long int.
- X */
- X
- char *ftob(s, val)
- char *s;
- double val;
- X{
- X unsigned long lval = (val<0.0 ? -val : val);
- X unsigned long i;
- X char *s0 = s;
- X
- X if (lval == 0)
- X *s++ = '0';
- X else
- X for (i = TwoToTheNLessOne; i; i>>=1)
- X if (lval & i)
- X *s++ = '1';
- X else {
- X *s = '0';
- X if (s != s0)
- X s++;
- X }
- X
- X *s = '\0';
- X return(s0);
- X}
- X
- X
- X
- X/*
- X * Takes a string containing a binary number and returns its
- X * decimal equivelant.
- X */
- X
- double btof(s)
- char *s;
- X{
- X unsigned long i, val = 0;
- X
- X for (i = (unsigned long)1<<(strlen(s)-1); i; i>>=1, s++)
- X if (*s == '1')
- X val |= i;
- X else if (*s != '0')
- X error("bad binary digit");
- X
- X
- X return((double) val);
- X}
- X
- X
- X
- X
- X/*
- X * Reads a line from the stdin, and puts it in s after striping
- X * off all spaces and tabs.
- X * Returns the length of s.
- X */
- X
- int getwhitlessline(s)
- char *s;
- X{
- X register int i, c;
- X
- X for(i = 0; i <= MAXLINE && ((c=getchar()) != '\n') && c!=EOF; i+=(c!=' ' && c!='\t'))
- X s[i] = c;
- X s[i] = '\0';
- X return(i);
- X}
- X
- X
- X
- X/*
- X * Displays an error message and exits unless a jmp_buf has been
- X * set to return to in just such emergencies. (Capt. Kirk always
- X * defined a jmp_buf.)
- X */
- X
- error(msg)
- char *msg;
- X{
- X printf("calc: error--%s\n", msg);
- X if (abort_on_err)
- X exit(1);
- X else
- X longjmp(err_recover, 0);
- X}
- X
- END_OF_FILE
- if test 11315 -ne `wc -c <'calc.c'`; then
- echo shar: \"'calc.c'\" unpacked with wrong size!
- fi
- # end of 'calc.c'
- fi
- if test -f 'calc.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'calc.man'\"
- else
- echo shar: Extracting \"'calc.man'\" \(5961 characters\)
- sed "s/^X//" >'calc.man' <<'END_OF_FILE'
- X.TH CALC 1L "24 February 1988" " " " "
- X
- X.de AI \"Init annotation environment.
- X.PD 0
- X.nf
- X.na
- X.ta .5i
- X..
- X.de AU \"Uninit annotation environment.
- X.PD
- X.fi
- X.ad
- X..
- X.de BA \"Begin annotation
- X.fi
- X.IP "\\$1" 25
- X..
- X.de EA \"End annotation
- X.nf
- X.PP
- X..
- X
- X.SH NAME
- calc \- a command line calculator
- X
- X.SH SYNOPSIS
- X.B calc
- X[
- X.B \-d \-h \-o \-b \-@
- X.BI \-p n
- X.B
- X\-e \-
- X]
- X[
- X.I expression
- X]
- X
- X.SH DESCRIPTION
- X.I calc
- evaluates mathematical expressions.
- X
- An expression is any decimal number in integer or real format. It may
- also be a binary, octal or hexidecimal integer prefixed by,
- respectively,
- X.I b,
- X.I o,
- or
- X.I h,
- or an ASCII character, prefixed by
- X.I @.
- X
- An expression is also any expression preceded by one of
- the following:
- X
- X.nf
- X.ta 1i 2i 3i
- X sin log - (unary minus)
- X cos ln + (unary plus)
- X tan sqrt ~ (one's complement)
- X atan exp
- X.fi
- X
- or any two expressions separated by one of the following operators:
- X
- X.nf
- X.ta 2i +.5i +.5i
- X.RS 1i
- Exponentiation: :
- Multiplication: * x X
- X (none: implied multiplication)
- Division: /
- Modulo: %
- Addition: +
- Subtraction: -
- Left shift: <
- Right shift: >
- Bitwise AND: &
- Bitwise XOR: ^
- BitWise OR: |
- X.RE
- X.fi
- X
- An expression is any expression preceded by an opening delimeter:
- X
- X.nf
- X.ta 1i +.5i +.5i
- X { [ (
- X.fi
- X
- and followed by a closing delimeter:
- X
- X
- X.nf
- X.ta 1i +.5i +.5i
- X } ] )
- X.fi
- X
- The special symbols "pi" and "PI" are also valid expressions. So is
- X"prev" which returns the value of the previous equation
- X(multiple-expression mode only).
- X
- If the expression is omitted from the command line, then the
- program will be in multiple-expression mode and repeatedly read
- expressions from the standard input until it encounters an empty
- line or an end of file.
- X
- X.SH OPTIONS
- X.IP\fB\-d\fP
- X(The default mode.) The answer is printed as a decimal
- number, or in scientific format if it is very large.
- X.IP\fB\-o\fP
- The answer is printed in octal, rounded down to the
- nearest integer.
- X.IP\fB\-h\fP
- The answer is printed in hexadecimal, rounded down to the
- nearest integer.
- X.IP\fB\-b\fP
- The answer is printed in binary, rounded down to the
- nearest integer.
- X.IP\fB\-@\fP
- The answer is printed as an ASCII character (modulo 128).
- X.IP\fB\-p\fP\fIn\fP
- Only meaningful in decimal and binary mode. Specifies the
- precision (the number of digits appearing after the decimal point)
- for a decimal number, or the number of minimum number of digits
- appearing in a binary number. (In order to line up the columns when
- multiple calculations are being performed.) There
- must not be a space between the ``\fBp\fP'' and
- X.I n.
- X.IP\fB\-e\fP
- Will cause
- X.I calc
- to exit when a bad expression is entered. This is only
- meaningful in multiple-expression mode.
- X.IP\fB\-\fP
- Indicates the end of the argument list. This is used
- when the beginning of the expression might accidently be
- interpreted as an option. (See EXAMPLES below.)
- X
- X.SH USAGE NOTES
- Arguments to trig functions are specified in degrees.
- X
- All binary operators group left-to-right, unary operators and functions
- group right-to-left. Priority of functions and operators is almost
- identical to that of C (except modulo is slightly lower here):
- X
- X.RS .5i
- X.nf
- X.ta 1.5i +1.75i
- Highest: Unary Op's Functions
- X Exponentiation
- X Multiplication Division
- X Modulo
- X Addition Subtraction
- X Left shift Right shift
- X And
- X Xor
- Lowest: Or
- X.fi
- X.RE
- X
- The C shell use many of
- X.IRcalc 's
- symbols for its own evil purposes. These include all three
- pairs of delimeters, and the asterisk. Whenever
- you need a delimeter, you are advised to enclose the entire
- expression in double quotes to keep the shell from messing with
- it. Alternatively, you can omit the expression from the command
- line, and have
- X.I calc
- prompt you for it, in which case the shell
- will never see what is typed.
- X
- Computations are performed using double precision floating point numbers
- with the following exceptions: The modulo operation (%) rounds its
- arguments to the nearest integer. Bitwise and bit shift operations
- expect (or will truncate to) positive integers. Hex and octal modes
- expect (or will truncate to) the nearest integer.
- When an integer is expected, it must be less than the
- largest long integer allowed on the machine (typically,
- X.if t 2\u\s-231\s0\d).
- X.if n 2:31).
- You will get undefined results if you go sticking large
- numbers where they don't belong.
- X
- X.SH EXAMPLES
- X.AI
- calc 2 + 5 x 6
- X 32
- X
- X.BA "calc '(2 + 5) x 6'"
- Parens quoted to hide them from the shell.
- X.EA
- X 42
- X
- calc -p2 "atan(tan(45))"
- X 45.00
- X
- calc -h 20
- X h14
- X
- calc -o @A
- X o101
- X
- X.BA "calc -b 2:8 + 3"
- Exponentiation takes precidence over addition.
- X.EA
- X b100000011
- X
- calc b101 - hc
- X -7
- X
- X.BA "calc - -h4ff"
- X``\fB-\fP'' used so ``\fB-h\fP'' won't be interpreted as an option
- X.EA
- X -1279
- X.AU
- X
- X.SH DIAGNOSTICS
- X.I calc
- prints its error messages on the
- X.B standard output.
- Normally, when an error occurs
- X.I calc
- terminates with an exit status of 1. The exception is when in
- multiple-expression mode if the
- X.I e
- option has
- X.B not
- been specified. In this case,
- X.I calc
- will simply report the error and move on to the next input.
- X
- The error messages are:
- X.RS .5i
- X.na
- X.IP "bad argument to -p option"
- Option must be followed by an integer argument with no
- intervening spaces.
- X.IP "missing expression"
- An operator of function expected an expression and didn't find one.
- X.IP "division by zero"
- Right-hand expression to the division operator evaluated to zero.
- X.IP "bad argument to modulo"
- Right-hand expression to the modulo operator was zero, or was
- greater than or equal to
- X.if t 2\u\s-231\s0\d.
- X.if n 2:31.
- X.IP "illegal expression"
- An expression couldn't be parsed.
- X.IP "unmatched open paren"
- A parenthesized expression was opened, but never closed.
- X.IP "bad binary digit"
- An expression preceded by a ``\fBb\fP'' contained a character
- other than ``1'' and ''0''.
- X.ad
- X.RE
- X
- X.SH BUGS
- Ascii format (-@, and @) doesn't do anything to pretty up control
- characters. For example, "calc -@ 12" may have a disconcerting result.
- X
- X
- X.SH AUTHOR
- Wayne Mesard, MESARD@BBN.COM
- END_OF_FILE
- if test 5961 -ne `wc -c <'calc.man'`; then
- echo shar: \"'calc.man'\" unpacked with wrong size!
- fi
- # end of 'calc.man'
- fi
- if test -f 'machine.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'machine.h'\"
- else
- echo shar: Extracting \"'machine.h'\" \(110 characters\)
- sed "s/^X//" >'machine.h' <<'END_OF_FILE'
- X#define Mch_Csz 8
- X#define Mch_Ssz 16
- X#define Mch_Isz 32
- X#define Mch_Lsz 32
- X#define Mch_BE 1
- X#define Mch_sgc 1
- END_OF_FILE
- if test 110 -ne `wc -c <'machine.h'`; then
- echo shar: \"'machine.h'\" unpacked with wrong size!
- fi
- # end of 'machine.h'
- fi
- if test -f 'mch_defines.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mch_defines.c'\"
- else
- echo shar: Extracting \"'mch_defines.c'\" \(2812 characters\)
- sed "s/^X//" >'mch_defines.c' <<'END_OF_FILE'
- X/* This program was snagged off the USENET comp.lang.c mailing list 22 July 1987 */
- X
- X/* The contents of the following program are copyright 1987 by John Cowan.
- It is hereby released to the public domain.
- X
- This program emits C #define statements to the standard output describing
- the machine it is executing on. The following #defines are generated:
- X Mch_Csz - size of a char, in bits
- X Mch_Ssz - size of a short int, in bits
- X Mch_Isz - size of a plain int, in bits
- X Mch_Lsz - size of a long int, in bits
- X Mch_BE - defined if the machine is big-endian; that is, if
- X the most significant byte in a number appears first.
- X Mch_LE - defined if the machine is little-endian; that is, if
- X the least significant byte in a number appears first.
- X Mch_PDP - defined if the machine uses PDP-11 byte ordering;
- X LE for bytes-in-a-word and BE for words-in-a-long.
- X Mch_ONE - defined if the machine uses one's complement arithmetic.
- X Mch_sgc - defined if characters can be signed.
- X*/
- X
- X#include <stdio.h>
- X
- char bittest[9] = "\001\001\001\001\001\001\001\001"; /*Changed from [6] for CRAY X-MP -WM*/
- char endtest[6] = "\001\002\003\004\005";
- long be = 1;
- long le = 1;
- long pdp;
- int byteoff;
- int bytesize;
- long longval;
- X
- main()
- X {
- X int i;
- X
- X byteoff = (*(int *) bittest & 2047) - 1;
- X switch (byteoff) {
- X case 256: bytesize = 8; break;
- X case 512: bytesize = 9; break;
- X case 1024: bytesize = 10; break;
- X default: fprintf(stderr, "mch: bogus byte size\n"); exit(1);
- X }
- X printf("#define Mch_Csz %d\n", bytesize);
- X printf("#define Mch_Ssz %d\n", sizeof(short) * bytesize);
- X printf("#define Mch_Isz %d\n", sizeof(int) * bytesize);
- X printf("#define Mch_Lsz %d\n", sizeof(long) * bytesize);
- X longval = *(long *) endtest;
- X for (i = 0; i < sizeof(long); i++) {
- X be *= byteoff;
- X be += endtest[i];
- X }
- X for (i = sizeof(long) - 1; i >= 0; i--) {
- X le *= byteoff;
- X le += endtest[i];
- X }
- X pdp = 0x02010403;
- X if (longval == be)
- X printf("#define Mch_BE 1\n");
- X else if (longval == le)
- X printf("#define Mch_LE 1\n");
- X else if (longval == pdp)
- X printf("#define Mch_PDP 1\n");
- X else {
- X fprintf(stderr, "mch: bogus endianism\n");
- X exit(1);
- X }
- X if (~0 == 0)
- X printf("#define Mch_ONE 1\n");
- X if ('\377' < 0) /* modified 1987/07/22 R. Dhesi */
- X printf("#define Mch_sgc 1\n");
- X }
- END_OF_FILE
- if test 2812 -ne `wc -c <'mch_defines.c'`; then
- echo shar: \"'mch_defines.c'\" unpacked with wrong size!
- fi
- # end of 'mch_defines.c'
- fi
- echo shar: End of shell archive.
- exit 0
-